home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termPacket.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-17
|
28KB
|
1,232 lines
/*
** termPacket.c
**
** Support routines for the `packet window'
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* A custom message structure. */
struct PacketMessage
{
struct Message VanillaMessage;
LONG Line;
};
/* Some private data required to handle both the window,
* the editing functions and the command history buffer.
*/
STATIC struct Hook PacketHook;
STATIC STRPTR PacketContents;
STATIC struct Process *PacketProcess;
STATIC struct SignalSemaphore PacketSemaphore;
STATIC struct MsgPort *PacketPort;
STATIC LONG PacketLine;
STATIC LONG PacketCount;
STATIC STRPTR PacketString = NULL;
STATIC LONG PacketX = -1,
PacketY = -1,
PacketWidth = -1,
PacketHeight = -1;
STATIC BYTE HasList = FALSE,
Echo = -1;
PacketSignal = -1;
/* Gadget IDs */
enum { GAD_STRING, GAD_LIST };
/* The menu to attach to the packet window. */
enum { MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,
MEN_TOGGLE_ECHO,MEN_QUITPANEL
};
STATIC struct NewMenu NewPacketMenu[] =
{
{ NM_TITLE, NULL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_LOADHISTORY},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_SAVEHISTORY},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_CLEARHISTORY},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_OTHERWINDOW},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , TICK, 0, (APTR)MEN_TOGGLE_ECHO},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, NULL, 0 , 0, 0, (APTR)MEN_QUITPANEL},
{ NM_END, 0, 0 , 0, 0, (APTR)0}
};
STATIC VOID __stdargs
PacketDestructor(struct MsgItem *Item)
{
Signal(PacketProcess,1L << PacketSignal);
}
STATIC VOID __regargs
PacketSerWrite(APTR Data,LONG Size)
{
struct DataMsg Msg;
InitMsgItem(&Msg,PacketDestructor);
Msg . Type = DATAMSGTYPE_WRITE;
Msg . Data = Data;
Msg . Size = Size;
Forbid();
ClrSignal(1L << PacketSignal);
PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
Wait(1L << PacketSignal);
Permit();
}
STATIC VOID __regargs
PacketSerialCommand(STRPTR String)
{
struct DataMsg Msg;
InitMsgItem(&Msg,PacketDestructor);
if(Echo)
Msg . Type = DATAMSGTYPE_SERIALCOMMAND;
else
Msg . Type = DATAMSGTYPE_SERIALCOMMANDNOECHO;
Msg . Data = String;
Forbid();
ClrSignal(1L << PacketSignal);
PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
Wait(1L << PacketSignal);
Permit();
}
/* SendPacketMsg(LONG Line):
*
* Tell the main process to display a certain line.
*/
STATIC VOID __regargs
SendPacketMsg(LONG Line)
{
struct PacketMessage *Msg;
if(Msg = (struct PacketMessage *)AllocVecPooled(sizeof(struct PacketMessage),MEMF_PUBLIC | MEMF_CLEAR))
{
Msg -> VanillaMessage . mn_Length = sizeof(struct PacketMessage);
Msg -> Line = Line;
PutMsg(PacketPort,Msg);
}
}
/* CreateAllGadgets():
*
* Create the packet string gadget.
*/
STATIC struct Gadget * __regargs
CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo)
{
struct Gadget *Gadget;
struct NewGadget NewGadget;
ObtainSemaphore(&PacketSemaphore);
memset(&NewGadget,0,sizeof(struct NewGadget));
if(Gadget = CreateContext(GadgetList))
{
WORD Rest,StringHeight,ProtoHeight;
StringHeight = 3 + TextAttr . tta_YSize + 3;
ProtoHeight = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 1 + StringHeight + 1 + Window -> WScreen -> WBorBottom;
Rest = (PacketHeight - 2 - ProtoHeight - 2) / TextAttr . tta_YSize;
NewGadget . ng_Width = Width - 26;
NewGadget . ng_Height = StringHeight;
NewGadget . ng_GadgetText = NULL;
NewGadget . ng_TextAttr = &TextAttr;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_GadgetID = GAD_STRING;
NewGadget . ng_Flags = 0;
NewGadget . ng_LeftEdge = 6;
NewGadget . ng_TopEdge = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 2;
GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GTST_MaxChars, 1024,
GTST_EditHook, &PacketHook,
GA_TabCycle, FALSE,
TAG_DONE);
/* If the window is large enough to display the
* list, create the list view gadget.
*/
if(Rest > 0)
{
NewGadget . ng_Height = 2 + Rest * TextAttr . tta_YSize + 2 + StringHeight;
NewGadget . ng_GadgetID = GAD_LIST;
GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
GTLV_ShowSelected, GadgetArray[GAD_STRING],
GTLV_Labels, &PacketHistoryList,
GTLV_Selected, PacketCount,
GTLV_Top, PacketCount,
TAG_DONE);
if(Gadget)
HasList = TRUE;
else
HasList = FALSE;
}
else
HasList = FALSE;
}
ReleaseSemaphore(&PacketSemaphore);
return(Gadget);
}
/* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
*
* This is a string gadget editing call back routine
* (a so-called `hook') which is to perform all the
* line editing and command history actions supported
* by the packet window.
*/
STATIC ULONG __saveds __asm
PacketKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
{
/* Someone activated the string gadget and
* hit a key.
*/
if(*Msg == SGH_KEY)
{
/* Right-Amiga-key was pressed, release the
* string gadget so user may select a menu
* item.
*/
if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
{
if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
return(TRUE);
else
{
Work -> Actions = (Work -> Actions & ~(SGA_USE | SGA_BEEP)) | SGA_END | SGA_REUSE;
Work -> Code = '\t';
CommandWindow = Work -> GadgetInfo -> gi_Window;
CommandGadget = Work -> Gadget;
}
}
if(Work -> IEvent -> ie_Code >= F01_CODE && Work -> IEvent -> ie_Code <= F10_CODE)
{
STATIC UBYTE __far OtherBuffer[2048];
STRPTR String;
LONG Len,Index = Work -> IEvent -> ie_Code - F01_CODE;
Forbid();
if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL)
String = MacroKeys -> Keys[3][Index];
else
{
if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
String = MacroKeys -> Keys[2][Index];
else
{
if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
String = MacroKeys -> Keys[1][Index];
else
String = MacroKeys -> Keys[0][Index];
}
}
if(Len = strlen(String))
{
if(Work -> BufferPos)
CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
OtherBuffer[Work -> BufferPos] = 0;
strcat(OtherBuffer,String);
strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
if(strlen(OtherBuffer) > 1023)
OtherBuffer[1023] = 0;
strcpy(Work -> WorkBuffer,OtherBuffer);
if(Work -> StringInfo -> UndoBuffer)
strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
Work -> StringInfo -> UndoPos = Work -> BufferPos;
Work -> BufferPos += Len;
Work -> NumChars += Len;
Work -> Actions = (Work -> Actions & ~SGA_BEEP) | SGA_USE | SGA_REDISPLAY;
}
Permit();
return(TRUE);
}
/* The user pressed the cursor-right key to
* move the cursor to the next word in the buffer.
*/
if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
{
if(Work -> BufferPos != Work -> NumChars)
{
WORD i,Position = -1;
for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
{
if(Work -> WorkBuffer[i] == ' ')
{
for( ; i < Work -> NumChars ; i++)
{
if(Work -> WorkBuffer[i] != ' ')
{
Position = i;
break;
}
}
break;
}
}
if(Position != -1)
Work -> BufferPos = Position;
else
Work -> BufferPos = Work -> NumChars;
Work -> EditOp = EO_MOVECURSOR;
}
return(TRUE);
}
/* The user pressed the cursor-right key to
* move the cursor to the previous word in the buffer.
*/
if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
{
if(Work -> BufferPos)
{
WORD i,Position = -1;
for(i = Work -> BufferPos ; i >= 0 ; i--)
{
if(Work -> WorkBuffer[i] != ' ')
{
Position = i;
break;
}
}
if(Position == -1)
Position = 0;
if(Position)
{
i = Position;
Position = -1;
for( ; i >= 0 ; i--)
{
if(Work -> WorkBuffer[i] == ' ')
{
Position = i + 1;
break;
}
}
}
if(Position != -1)
Work -> BufferPos = Position;
else
Work -> BufferPos = 0;
Work -> EditOp = EO_MOVECURSOR;
}
}
/* The user pressed the cursor-up key to
* scroll through the command history.
*/
if(Work -> IEvent -> ie_Code == CURSORUP)
{
/* Shift key: jump to first command
* history entry.
*/
if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
{
if(PacketLine)
SendPacketMsg(0);
}
else
{
if(PacketLine && PacketCount > 0)
SendPacketMsg(PacketCount - 1);
}
}
/* The user pressed the cursor-down key to
* scroll through the command history.
*/
if(Work -> IEvent -> ie_Code == CURSORDOWN)
{
/* Shift key: jump to last command
* history entry.
*/
if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
{
if(PacketLine > 0)
SendPacketMsg(PacketLine);
}
else
{
if(PacketCount < PacketLine)
SendPacketMsg(PacketCount + 1);
}
}
return(TRUE);
}
else
{
if(*Msg == SGH_CLICK)
return(TRUE);
else
return(FALSE);
}
}
/* HandlePacket():
*
* Process the input coming through the packet window.
*/
STATIC BOOLEAN
HandlePacket(VOID)
{
struct IntuiMessage *Message;
struct PacketMessage *PacketMsg;
ULONG MsgClass,MsgCode;
struct Gadget *MsgGadget;
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
BOOLEAN SwapWindow = FALSE;
FOREVER
{
if(Wait(PORTMASK(PacketWindow -> UserPort) | SIG_KILL) & SIG_KILL)
return(TRUE);
while(Message = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
{
MsgClass = Message -> Class;
MsgCode = Message -> Code;
MsgGadget = (struct Gadget *)Message -> IAddress;
GT_ReplyIMsg(Message);
/* Re-enable the string gadget if necessary. */
if(MsgClass == IDCMP_RAWKEY)
{
if(MsgCode == IECODE_UP_PREFIX|RAMIGA_CODE && CommandWindow == PacketWindow)
ActivateGadget(CommandGadget,PacketWindow,NULL);
if(MsgCode == HELP_CODE)
GuideDisplay(CONTEXT_PACKETWINDOW);
}
/* Menu help is required. */
if(MsgClass == IDCMP_MENUHELP)
GuideDisplay(CONTEXT_PACKET_MENU);
/* Handle the menu. */
if(MsgClass == IDCMP_MENUPICK)
{
struct MenuItem *MenuItem;
while(MsgCode != MENUNULL)
{
MenuItem = ItemAddress(PacketMenu,MsgCode);
switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
{
case MEN_TOGGLE_ECHO:
if(MenuItem -> Flags & CHECKED)
Echo = TRUE;
else
Echo = FALSE;
break;
case MEN_QUITPANEL:
MsgClass = IDCMP_CLOSEWINDOW;
break;
case MEN_LOADHISTORY:
LT_LockWindow(PacketWindow);
if(FileRequest = GetFile(PacketWindow,LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
{
if(GetFileSize(DummyBuffer))
{
BPTR SomeFile;
if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
{
if(PacketLine)
{
switch(MyEasyRequest(PacketWindow,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
{
case 1: ClearPacketHistory();
break;
case 0: Close(SomeFile);
SomeFile = NULL;
break;
}
}
if(SomeFile)
{
WORD Len;
LineRead(NULL,NULL,NULL);
while(Len = LineRead(SomeFile,DummyBuffer,255))
{
DummyBuffer[Len - 1] = 0;
AddPacketHistory(DummyBuffer);
}
Close(SomeFile);
}
}
else
ShowError(PacketWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
}
FreeAslRequest(FileRequest);
}
LT_UnlockWindow(PacketWindow);
break;
case MEN_SAVEHISTORY:
LT_LockWindow(PacketWindow);
if(!PacketLine)
MyEasyRequest(PacketWindow,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
else
{
if(FileRequest = GetFile(PacketWindow,LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
{
BPTR SomeFile = NULL;
LONG Error = 0;
/* If the file we are about
* to create already exists,
* ask the user whether we are
* to create, append or skip
* the file.
*/
if(GetFileSize(DummyBuffer))
{
switch(MyEasyRequest(PacketWindow,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
{
case 1: SomeFile = Open(DummyBuffer,MODE_NEWFILE);
break;
case 2: if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
{
if(Seek(SomeFile,0,OFFSET_END) == -1)
{
Close(SomeFile);
SomeFile = NULL;
}
}
break;
}
}
else
SomeFile = Open(DummyBuffer,MODE_NEWFILE);
if(!SomeFile)
Error = IoErr();
else
{
struct Node *SomeNode;
ObtainSemaphore(&PacketSemaphore);
SomeNode = PacketHistoryList . lh_Head;
while(SomeNode -> ln_Succ)
{
SetIoErr(0);
if(FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name) < 1)
{
Error = IoErr();
break;
}
SomeNode = SomeNode -> ln_Succ;
}
Close(SomeFile);
if(GetFileSize(DummyBuffer))
{
AddProtection(DummyBuffer,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
}
else
DeleteFile(DummyBuffer);
ReleaseSemaphore(&PacketSemaphore);
}
if(Error)
ShowError(PacketWindow,ERR_SAVE_ERROR,Error,DummyBuffer);
FreeAslRequest(FileRequest);
}
}
LT_UnlockWindow(PacketWindow);
break;
case MEN_CLEARHISTORY:
LT_LockWindow(PacketWindow);
ClearPacketHistory();
LT_UnlockWindow(PacketWindow);
break;
case MEN_OTHERWINDOW:
SwapWindow = TRUE;
break;
}
MsgCode = MenuItem -> NextSelect;
}
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
}
/* Shut down. */
if(MsgClass == IDCMP_CLOSEWINDOW)
{
Forbid();
if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
return(FALSE);
else
return(TRUE);
}
/* Activate the string gadget as well. */
if(MsgClass == IDCMP_ACTIVEWINDOW)
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
if(MsgClass == IDCMP_NEWSIZE)
{
PacketWindow -> Flags |= WFLG_RMBTRAP;
strcpy(DummyBuffer,PacketContents);
RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
FreeGadgets(PacketGadgetList);
PacketGadgetList = NULL;
SetAPen(PacketWindow -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
RefreshWindowFrame(PacketWindow);
PacketHeight = PacketWindow -> Height;
PacketWidth = PacketWindow -> Width;
ObtainSemaphore(&PacketSemaphore);
if(CreateAllGadgets(PacketWindow -> Width,PacketGadgetArray,&PacketGadgetList,VisualInfo))
{
PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo) -> Buffer;
AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PacketWindow,NULL);
ReleaseSemaphore(&PacketSemaphore);
PacketWindow -> Flags &= ~WFLG_RMBTRAP;
GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
GTST_String, DummyBuffer,
TAG_DONE);
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
}
else
{
DisplayBeep(PacketWindow -> WScreen);
ReleaseSemaphore(&PacketSemaphore);
if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
return(FALSE);
else
return(TRUE);
}
}
if(MsgClass == IDCMP_MOUSEBUTTONS)
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
/* User has entered a string. */
if(MsgClass == IDCMP_GADGETUP)
{
switch(MsgGadget -> GadgetID)
{
case GAD_STRING:
if(MsgCode != '\t')
{
/* Is there anything in the buffer at all? */
if(PacketContents[0])
{
strcpy(DummyBuffer,PacketContents);
if(PacketString)
{
if(strcmp(PacketString,DummyBuffer))
AddPacketHistory(DummyBuffer);
PacketString = NULL;
}
else
AddPacketHistory(DummyBuffer);
/* Convert alien IBM characters. */
if(Config -> TerminalConfig -> FontMode == FONT_IBM)
{
UBYTE Char;
WORD i;
for(i = 0 ; i < strlen(DummyBuffer) ; i++)
{
if(Char = IBMConversion[DummyBuffer[i]])
DummyBuffer[i] = Char;
}
}
/* Execute the command. */
PacketSerialCommand(DummyBuffer);
}
/* Clear the packet window string
* gadget.
*/
GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
GTST_String, "",
TAG_DONE);
/* Send a terminating `CR'. */
switch(Config -> TerminalConfig -> SendCR)
{
case EOL_CR:
PacketSerWrite("\r",1);
break;
case EOL_LF:
PacketSerWrite("\n",1);
break;
case EOL_CRLF:
PacketSerWrite("\r\n",2);
break;
case EOL_LFCR:
PacketSerWrite("\n\r",2);
break;
}
/* Re-activate the string gadget. */
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
}
break;
case GAD_LIST:
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
break;
}
}
if(SwapWindow)
{
BumpWindow(Window);
SwapWindow = FALSE;
}
}
if(PacketMsg = (struct PacketMessage *)GetMsg(PacketPort))
{
struct Node *Node;
ObtainSemaphore(&PacketSemaphore);
if(Node = GetListNode(PacketMsg -> Line,&PacketHistoryList))
{
PacketString = Node -> ln_Name;
if(HasList)
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
GTLV_Selected, PacketMsg -> Line,
GTLV_Top, PacketMsg -> Line,
TAG_DONE);
}
else
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
GTST_String, Node -> ln_Name,
TAG_DONE);
}
}
else
{
PacketString = NULL;
GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
GTST_String, "",
TAG_DONE);
}
ReleaseSemaphore(&PacketSemaphore);
PacketCount = PacketMsg -> Line;
FreeVecPooled(PacketMsg);
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
}
}
}
STATIC VOID __saveds
PacketProcessEntry(VOID)
{
BOOLEAN RingBack = TRUE;
if((PacketSignal = AllocSignal(-1)) != -1)
{
if(PacketPort = (struct MsgPort *)AllocVecPooled(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
{
struct Message *Message;
if(PacketMenu = CreateMenus(NewPacketMenu,TAG_DONE))
{
if(LayoutMenus(PacketMenu,VisualInfo,
GTMN_TextAttr, &UserFont,
GTMN_NewLookMenus, TRUE,
AmigaGlyph ? GTMN_AmigaKey : TAG_IGNORE, AmigaGlyph,
CheckGlyph ? GTMN_Checkmark : TAG_IGNORE, CheckGlyph,
TAG_DONE))
{
LONG ProtoHeight;
ProtoHeight = Window -> WScreen -> WBorTop + Window -> WScreen -> Font -> ta_YSize + 1 + 1 + 3 + TextAttr . tta_YSize + 3 + 1 + Window -> WScreen -> WBorBottom;
if(PacketWidth == -1)
PacketWidth = Window -> Width;
if(PacketHeight < ProtoHeight)
PacketHeight = ProtoHeight;
if(PacketX == -1 || (PacketX + PacketWidth > Window -> WScreen -> Width))
{
PacketX = Window -> LeftEdge;
if(PacketX + PacketWidth > Window -> WScreen -> Width)
PacketWidth = Window -> WScreen -> Width - PacketX;
}
if(PacketY == -1 || (PacketY + PacketHeight > Window -> WScreen -> Height))
{
PacketY = Window -> TopEdge + Window -> Height;
if(PacketY + PacketHeight > Window -> WScreen -> Height)
PacketHeight = ProtoHeight;
}
if(CreateAllGadgets(PacketWidth,PacketGadgetArray,&PacketGadgetList,VisualInfo))
{
if(PacketWindow = OpenWindowTags(NULL,
WA_Width, PacketWidth,
WA_Height, PacketHeight,
WA_Left, PacketX,
WA_Top, PacketY,
WA_Activate, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_SizeGadget, TRUE,
WA_MinWidth, 80,
WA_MinHeight, ProtoHeight,
WA_MaxWidth, Window -> WScreen -> Width,
WA_MaxHeight, Window -> WScreen -> Height,
WA_CustomScreen, Window -> WScreen,
WA_NoCareRefresh, TRUE,
WA_NewLookMenus, TRUE,
WA_BackFill, &BackfillHook,
WA_IDCMP, STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS | IDCMP_MENUHELP,
WA_MenuHelp, TRUE,
WA_Title, LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
AmigaGlyph ? WA_AmigaKey : TAG_IGNORE, AmigaGlyph,
CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
TAG_DONE))
{
APTR OldPtr;
SetAPen(PacketWindow -> RPort,DrawInfo -> dri_Pens[BACKGROUNDPEN]);
SetDrMd(PacketWindow -> RPort,JAM1);
RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - (PacketWindow -> BorderRight + 1),PacketWindow -> Height - (PacketWindow -> BorderBottom + 1));
PacketPort -> mp_Flags = PA_SIGNAL;
PacketPort -> mp_SigBit = PacketWindow -> UserPort -> mp_SigBit;
PacketPort -> mp_SigTask = PacketWindow -> UserPort -> mp_SigTask;
NewList(&PacketPort -> mp_MsgList);
PacketHook . h_Entry = (LONG (*)())PacketKey;
PacketHook . h_SubEntry = NULL;
PacketHook . h_Data = NULL;
PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo) -> Buffer;
AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PacketWindow,NULL);
SetMenuStrip(PacketWindow,PacketMenu);
PacketWindow -> Flags &= ~WFLG_RMBTRAP;
ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
PacketProcess = (struct Process *)FindTask(NULL);
OldPtr = PacketProcess -> pr_WindowPtr;
PacketProcess -> pr_WindowPtr = PacketWindow;
Signal(ThisProcess,SIG_HANDSHAKE);
RingBack = HandlePacket();
PacketProcess -> pr_WindowPtr = OldPtr;
PacketWindow -> Flags |= WFLG_RMBTRAP;
ClearMenuStrip(PacketWindow);
RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
PacketX = PacketWindow -> LeftEdge;
PacketY = PacketWindow -> TopEdge;
PacketWidth = PacketWindow -> Width;
PacketHeight = PacketWindow -> Height;
LT_DeleteWindowLock(PacketWindow);
CloseWindow(PacketWindow);
PacketWindow = NULL;
}
FreeGadgets(PacketGadgetList);
PacketGadgetList = NULL;
}
}
FreeMenus(PacketMenu);
PacketMenu = NULL;
}
while(Message = GetMsg(PacketPort))
FreeVecPooled(Message);
FreeVecPooled(PacketPort);
PacketPort = NULL;
}
FreeSignal(PacketSignal);
PacketSignal = -1;
}
Forbid();
PacketProcess = NULL;
if(RingBack)
Signal(ThisProcess,SIG_HANDSHAKE);
else
CheckItem(MEN_PACKET_WINDOW,FALSE);
}
/* ClearPacketHistory():
*
* Release the command history.
*/
VOID
ClearPacketHistory()
{
if(PacketProcess)
{
ObtainSemaphore(&PacketSemaphore);
if(HasList)
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
GTLV_Labels,~0,
TAG_DONE);
}
FreeList(&PacketHistoryList);
PacketCount = PacketLine = 0;
if(HasList)
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
GTLV_Labels,&PacketHistoryList,
TAG_DONE);
}
PacketString = NULL;
ReleaseSemaphore(&PacketSemaphore);
}
}
/* AddPacketHistory(STRPTR Buffer):
*
* Add a line to the packet window command history. This
* works very much the same as the AddLine()-routine.
*/
VOID __regargs
AddPacketHistory(STRPTR Buffer)
{
if(PacketProcess)
{
struct Node *SomeNode;
ObtainSemaphore(&PacketSemaphore);
if(HasList)
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
GTLV_Labels, ~0,
TAG_DONE);
}
if(SomeNode = CreateNode(Buffer))
{
AddTail(&PacketHistoryList,SomeNode);
PacketCount = ++PacketLine;
}
if(HasList)
{
GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
GTLV_Top, PacketCount - 1,
GTLV_Labels, &PacketHistoryList,
TAG_DONE);
}
ReleaseSemaphore(&PacketSemaphore);
}
}
/* DeletePacketWindow():
*
* Delete the packet window and release the command
* history.
*/
VOID __regargs
DeletePacketWindow(BYTE WindowOnly)
{
CheckItem(MEN_PACKET_WINDOW,FALSE);
if(PacketProcess)
{
Forbid();
ClrSignal(SIG_HANDSHAKE);
Signal(PacketProcess,SIG_KILL);
Wait(SIG_HANDSHAKE);
Permit();
if(!WindowOnly)
{
HasList = FALSE;
FreeList(&PacketHistoryList);
PacketCount = PacketLine = 0;
PacketString = NULL;
}
}
}
/* CreatePacketWindow():
*
* Open the packet window and allocate the command history
* buffer.
*/
BYTE
CreatePacketWindow()
{
if(Echo == -1)
Echo = Config -> SerialConfig -> Duplex;
if(!PacketProcess)
{
InitSemaphore(&PacketSemaphore);
LocalizeMenu(NewPacketMenu,MSG_PACKET_PROJECT_MEN);
Forbid();
if(CreateNewProcTags(
NP_Name, "term Packet Process",
NP_Priority, SysBase -> ThisTask -> tc_Node . ln_Pri,
NP_Entry, PacketProcessEntry,
NP_StackSize, 6000,
TAG_DONE))
{
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
}
Permit();
}
if(PacketProcess)
{
Forbid();
ActivateWindow(PacketWindow);
CheckItem(MEN_PACKET_WINDOW,TRUE);
Permit();
return(TRUE);
}
else
{
CheckItem(MEN_PACKET_WINDOW,FALSE);
return(FALSE);
}
}